#include <REGX52.H>
#include "OneWire.h"

sbit OneWire_DQ = P3^7;		//端口

//单总线

/*初始化
	主机 将总线拉低至少480us，然后释放总线，
	等待15~60us后，存在的 从机 会拉低总线60~240us以响应 主机
	之后 从机 将释放总线
*/
unsigned char OneWire_Init(void)
{
	unsigned char i;
	unsigned char AckBit;
	OneWire_DQ = 1;	//先给总线置1
	OneWire_DQ = 0;	//再拉低总线

	i = 230; while (--i);	//延时500us（至少拉低总线480us）
	OneWire_DQ = 1;			//然后释放总线
	i = 32; while (--i);	//延时70us
	AckBit = OneWire_DQ;	//读出I/O口电平，存放在AckBit
	i = 230; while (--i);	//延时500us（也是至少480us）
	return AckBit;
}

/*发送一位
	主机将总线拉低60~120us，然后释放总线，表示发送0；
	主机将总线拉低1~15us，然后释放总线，表示发送1。
	从机 将在总线拉低30us后读取电平，整个时间片应大于60us
	*/
void OneWire_SendBit(unsigned char Bit)
{
	
	unsigned char i;
	OneWire_DQ = 0;			//先直接拉低，初始化之后总线是1,
	i = 4;	while (--i);	//延时10us
	OneWire_DQ = Bit;		//10us后将Bit送回总线
	i = 23;	while (--i);	//延时50us
	OneWire_DQ = 1;			//最后释放总线
}

/*接收一位
	主机将总线拉低1~15us，然后释放总线，并在拉低后15us内读取总线电平（尽量贴近15us末尾）
	读取为低电平则为接收0，读取为高电平则为接收1，整个时间片应大于60us
	*/
unsigned char OneWire_ReceiveBit(void)
{	
	unsigned char i;
	unsigned char Bit;
	OneWire_DQ = 0;			//主机将总线拉低1~15us
	i = 2;	while (--i);	//延时5us
	OneWire_DQ = 1;			//释放总线
	i = 2;	while (--i);	//延时5us
	Bit = OneWire_DQ;		//采样、读取电平（读取到0就是从机给拉低了）
	i = 23;	while (--i);	//延时50us
	//结束后 从机 会自动释放总线 
	return Bit;
}

//发送一个字节，从低位开始发送
void OneWire_SendByte(unsigned char Byte)
{	
	unsigned char i;
	for(i=0;i<8;i++)
	{
		OneWire_SendBit(Byte&(0x01<<i));
	}	
}

//接收一个字节
unsigned char OneWire_ReceiveByte(void)
{
	unsigned char i;
	unsigned char Byte = 0x00;
	for(i=0;i<8;i++)
	{
		if(OneWire_ReceiveBit()) {Byte |= (0x01<<i);} //从低位到高位依次取出
		//这个if判断，判断为0的时候，Byte当前位还是0
	}
	return Byte;
}

